package com.vito.oa.email.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Provider;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.URLName;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import javax.mail.search.AndTerm;
import javax.mail.search.ComparisonTerm;
import javax.mail.search.FlagTerm;
import javax.mail.search.ReceivedDateTerm;
import javax.mail.search.SearchTerm;
import javax.mail.search.SentDateTerm;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sun.mail.imap.IMAPFolder;
import com.vito.base.model.DataGrid;
import com.vito.base.util.DateUtils;
import com.vito.base.util.StringUtil;
import com.vito.oa.email.action.OaEmailConstant;
import com.vito.oa.email.model.ExternalContacts;
import com.vito.oa.email.model.OaEmailConfig;
import com.vito.oa.email.model.OaEmailMessage;
import com.vito.oa.email.model.VitoImapProvider;
import com.vito.oa.email.model.VitoImapStore;
import com.vito.oa.email.service.OaBaseUserService;

import redis.clients.jedis.tool.JedisTool;

public class OaEmailUtil {
	
	private static final Logger log = LoggerFactory.getLogger(OaEmailUtil.class);
	
	public static OaBaseUserService baseUserService;
	
	private static String sentFolder = StringUtil.getProperties("conf/email","email.sent.folder");
	private static String draftFolder = StringUtil.getProperties("conf/email","email.draft.folder");
	private static String recycleFolder = StringUtil.getProperties("conf/email", "email.recycle.folder");
	

	public static DataGrid<OaEmailMessage> getEmailPage(OaEmailMessage emailMessage, OaEmailConfig emailConfig) {
		DataGrid<OaEmailMessage> emailPager = new DataGrid<OaEmailMessage>();
		try {
			Store store = emailConfig.getStore();
			// 获得收件箱 
			IMAPFolder folder = (IMAPFolder)store.getFolder(emailConfig.getFolder()); 
	        // 以读写模式打开收件箱 
	        folder.open(Folder.READ_ONLY); 
	        List<SearchTerm> list = getSearchConditionList(emailMessage);
		    if (list.size() > 0) {
		    	SearchTerm[] where = new SearchTerm[list.size()];
		    	SearchTerm andTerm = new AndTerm(list.toArray(where));
		    	emailPager = getSearchList(folder, andTerm, emailMessage, emailConfig);
		    } else {
		    	emailPager = getNotSearchList(folder, emailMessage, emailConfig);
		    }
		    closeStoreAndFloder(folder, store);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return emailPager;
	}
	
	public static DataGrid<OaEmailMessage> getRecycleEmaile(OaEmailMessage emailMessage, OaEmailConfig emailConfig) {
		DataGrid<OaEmailMessage> emailPager = new DataGrid<OaEmailMessage>();
		try {
			Store store = emailConfig.getStore();
			// 获得收件箱 
			IMAPFolder folder = (IMAPFolder)store.getFolder(emailConfig.getFolder()); 
	        // 以读写模式打开收件箱 
	        folder.open(Folder.READ_ONLY); 
	        List<SearchTerm> list = getSearchConditionList(emailMessage);
		    if (list.size() > 0) {
		    	SearchTerm[] where = new SearchTerm[list.size()];
		    	SearchTerm andTerm = new AndTerm(list.toArray(where));
		    	emailPager = getSearchList(folder, andTerm, emailMessage, emailConfig);
		    } else {
		    	emailPager = getNotSearchList(folder, emailMessage, emailConfig);
		    }
		    closeStoreAndFloder(folder, store);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return emailPager;
	}
	
	
	
	public static DataGrid<OaEmailMessage> getSentEmailPage(OaEmailMessage emailMessage, OaEmailConfig emailConfig) {
		DataGrid<OaEmailMessage> emailPager = new DataGrid<OaEmailMessage>();
		try {
			Store store = emailConfig.getStore();
			// 获得收件箱 
			IMAPFolder folder =  (IMAPFolder)store.getFolder(emailConfig.getFolder()); 
	        // 以读写模式打开收件箱 
	        folder.open(Folder.READ_ONLY); 
	        List<SearchTerm> list = getSearchConditionList(emailMessage);
	        if (list.size() > 0) {
		    	SearchTerm[] where = new SearchTerm[list.size()];
		    	SearchTerm andTerm = new AndTerm(list.toArray(where));
		    	emailPager = getSearchList(folder, andTerm, emailMessage, emailConfig);
		    } else {
		    	emailPager = getNotSearchList(folder, emailMessage, emailConfig);
		    }
	        closeStoreAndFloder(folder, store);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return emailPager;
	}
	
	public static DataGrid<OaEmailMessage> getDraftEmailPage(OaEmailMessage emailMessage, OaEmailConfig emailConfig) {
		DataGrid<OaEmailMessage> emailPager = new DataGrid<OaEmailMessage>();
		try {
			Store store = emailConfig.getStore();;
			// 获得收件箱 
			IMAPFolder folder =  (IMAPFolder)store.getFolder(emailConfig.getFolder()); 
	        // 以读写模式打开收件箱 
	        folder.open(Folder.READ_ONLY); 
	        List<SearchTerm> list = getSearchConditionList(emailMessage);
	        if (list.size() > 0) {
		    	SearchTerm[] where = new SearchTerm[list.size()];
		    	SearchTerm andTerm = new AndTerm(list.toArray(where));
		    	emailPager = getSearchList(folder, andTerm, emailMessage, emailConfig);
		    } else {
		    	emailPager = getNotSearchList(folder, emailMessage, emailConfig);
		    }
	        closeStoreAndFloder(folder, store);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return emailPager;
	}
	
	public static OaEmailMessage getViewEmail(Long number, int folderType, OaEmailConfig emailConfig, OaBaseUserService oaBaseUserService) {
		OaEmailMessage email = new OaEmailMessage();
		try {
			baseUserService = oaBaseUserService;
			Store store = emailConfig.getStore();
			// 获得收件箱 
			IMAPFolder folder =  (IMAPFolder)store.getFolder(emailConfig.getFolder()); 
	        // 以读写模式打开收件箱 
	        folder.open(Folder.READ_WRITE); 
	        // 获得收件箱的邮件列表 
	        Message message = folder.getMessageByUID(number);
	        MimeMessage msg = (MimeMessage) message;
	        //判断邮件为未读并且需要回执
	        //1、收件箱 2、发件箱、3草稿箱
	        if (folderType == OaEmailConstant.FOLDER_TYPE_INBOX || folderType == OaEmailConstant.FOLDER_TYPE_DRAFT) {
	        	Flags flags = message.getFlags();
	        	if (!flags.contains(Flags.Flag.SEEN) && getReplySign(msg)) {
	        		email.setReplyTo(true);
	        	} else {
	        		email.setReplyTo(false);
	        	}
	        }
    		email.setNumber(number);
    		email.setSeenFlag(true);
    		email.setFromAddressList(parserFromAddress(msg, emailConfig.getUserId()));
    		email.setSubject(message.getSubject());
    		if (folderType == OaEmailConstant.FOLDER_TYPE_INBOX) {
    			email.setReceivedDate(getSentDate(message.getReceivedDate()));
    		}
    		if (folderType == OaEmailConstant.FOLDER_TYPE_SEND || folderType == OaEmailConstant.FOLDER_TYPE_DRAFT) {
    			email.setSendDate(getSentDate(message.getSentDate()));
    		}
    		email.setToAddressList(getReceiveAddress(msg, Message.RecipientType.TO, emailConfig.getUserId()));
    		email.setCcAddressList(getReceiveAddress(msg, Message.RecipientType.CC, emailConfig.getUserId()));
    		email.setBccAddressList(getReceiveAddress(msg, Message.RecipientType.BCC, emailConfig.getUserId()));
    		StringBuffer bodyText = new StringBuffer();
    		email.setEmailText(getMailContent(bodyText, msg));
    		List<Map<String, Object>> fileList = new ArrayList<Map<String,Object>>();
    		email.setFileList(getFileNames(fileList, msg));
    		//设置为已读
    		if (folderType == OaEmailConstant.FOLDER_TYPE_INBOX) {
    			message.setFlag(Flags.Flag.SEEN, true);
    		}
    		if (folderType == OaEmailConstant.FOLDER_TYPE_DRAFT) {
    			email.setPriority(getPriority(msg));
    		}
    		closeStoreAndFloder(folder, store);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return email;
	}
	public static boolean sendEmail(OaEmailMessage emailMessage, OaEmailConfig emailConfig, boolean draft) {
		boolean b = false;
		try {
			Properties props = new Properties();
			Store store = null;
			props.put("mail.smtp.host", emailConfig.getHost());
			props.setProperty("mail.smtp.port", emailConfig.getPort());
			props.setProperty("mail.imap.proxyauth.user", emailConfig.getHrefPath());
			props.setProperty("mail.imap.class", VitoImapStore.class.getName());
			props.setProperty("LOGINDISABLED", "true");
			Session session = Session.getInstance(props);
			session.addProvider(new VitoImapProvider(Provider.Type.STORE, "imap", null, "Sun Microsystems, Inc", null));;
			URLName urln = new URLName(emailConfig.getUrlName());
			try {
				store = session.getStore(urln);
				store.connect();
			} catch (Exception e) {
				log.info("连接邮件服务器失败");
				e.printStackTrace();
			}
			//打开发送文件夹
			Folder folder = null;
			if (draft) { //保存草稿箱
				folder = store.getFolder(draftFolder);
			} else {
				folder = store.getFolder(sentFolder);
			}
			MimeMessage message = new MimeMessage(session);
	        message.setFrom(new InternetAddress(emailMessage.getFromAddressList().get(0).get("email"), encodeUtil(emailMessage.getFromAddressList().get(0).get("personal"))));
	        message.setSubject(encodeUtil(emailMessage.getSubject()));
	        message.setText(emailMessage.getEmailText());
	        message.setSentDate(new Date());
	        message.setContent(buildMimeMultipart(emailMessage.getEmailText(), emailMessage.getFileList())); 
	        message.saveChanges(); 
	        message.setFlag(Flags.Flag.RECENT, true);//新邮件
	        //设置优先级(1:紧急   3:普通    5:低) 
	        message.setHeader("X-Priority", emailMessage.getPriority());
	        if (emailMessage.isReplyTo()) {//要求阅读回执
	        	//设置回复人(收件人回复此邮件时,默认收件人) 
//	        	message.setReplyTo(createAddress(emailMessage.getFromAddress()));
	        	message.setReplyTo(createAddress(emailMessage.getFromAddressList()));
	        	//要求阅读回执(收件人阅读邮件时会提示回复发件人,表明邮件已收到,并已阅读) 
	        	message.setHeader("Disposition-Notification-To", emailMessage.getFromAddressList().get(0).get("email"));
	        }
	    	if (emailMessage.getToAddressList() != null && emailMessage.getToAddressList().size() > 0) {
	    		message.setRecipients(Message.RecipientType.TO, createAddress(emailMessage.getToAddressList())); //发送
	    	}
	    	if (emailMessage.getCcAddressList() != null && emailMessage.getCcAddressList().size() > 0) {
	    		message.setRecipients(Message.RecipientType.CC, createAddress(emailMessage.getCcAddressList()));
	    	}
	    	if (emailMessage.getBccAddressList() != null && emailMessage.getBccAddressList().size() > 0) { //密送
	    		message.setRecipients(Message.RecipientType.BCC, createAddress(emailMessage.getBccAddressList()));
	    	}
	    	if (!draft) { 
	    		Transport.send(message);
	    	}
//	    	message.reply(false);
	    	MimeMessage draftMessages[] = {(MimeMessage)message};
	    	folder.appendMessages(draftMessages);
	    	b = true;
	    	log.info("发送成功");
	    	closeStoreAndFloder(folder, store);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return b;
	}
	
	public static boolean replyEmail(OaEmailMessage emailMessage, OaEmailConfig emailConfig, boolean saveSend) {
		boolean b = false;
		try {
			Properties props = new Properties();
			Store store = null;
			props.put("mail.smtp.host", emailConfig.getHost());
			props.setProperty("mail.smtp.port", emailConfig.getPort());
			props.setProperty("mail.imap.proxyauth.user", emailConfig.getHrefPath());
			props.setProperty("mail.imap.class", VitoImapStore.class.getName());
			props.setProperty("LOGINDISABLED", "true");
			Session session = Session.getInstance(props);
			session.addProvider(new VitoImapProvider(Provider.Type.STORE, "imap", null, "Sun Microsystems, Inc", null));;
			URLName urln = new URLName(emailConfig.getUrlName());
			try {
				store = session.getStore(urln);
				store.connect();
			} catch (Exception e) {
				log.info("连接邮件服务器失败");
				e.printStackTrace();
			}
			//先获取要回复邮件
			IMAPFolder folder = (IMAPFolder)store.getFolder(emailConfig.getFolder()); 
			// 以读写模式打开收件箱 
	        folder.open(Folder.READ_WRITE);
	        Message replyMessage = new MimeMessage(session);
	        Message msg = folder.getMessageByUID(emailMessage.getNumber());
	        replyMessage = msg.reply(false);
	        if (emailMessage.getSubject() != null && emailMessage.getSubject() != "") {
	        	replyMessage.setSubject(encodeUtil(emailMessage.getSubject()));
	        }
	        replyMessage.setFrom(new InternetAddress(emailMessage.getFromAddressList().get(0).get("email"), encodeUtil(emailMessage.getFromAddressList().get(0).get("personal"))));
	        if (emailMessage.getToAddressList() != null && emailMessage.getToAddressList().size() > 0) {
	        	replyMessage.setRecipients(Message.RecipientType.TO, createAddress(emailMessage.getToAddressList())); //发送
	    	}
	    	if (emailMessage.getCcAddressList() != null && emailMessage.getCcAddressList().size() > 0) {
	    		replyMessage.setRecipients(Message.RecipientType.CC, createAddress(emailMessage.getCcAddressList()));
	    	}
	    	if (emailMessage.getBccAddressList() != null && emailMessage.getBccAddressList().size() > 0) { //密送
	    		replyMessage.setRecipients(Message.RecipientType.BCC, createAddress(emailMessage.getBccAddressList()));
	    	}
	    	//设置优先级(1:紧急   3:普通    5:低) 
	    	replyMessage.setHeader("X-Priority", emailMessage.getPriority());
	        if (emailMessage.isReplyTo()) {//要求阅读回执
	        	//设置回复人(收件人回复此邮件时,默认收件人) 
//	        	message.setReplyTo(createAddress(emailMessage.getFromAddress()));
	        	replyMessage.setReplyTo(createAddress(emailMessage.getFromAddressList()));
	        	//要求阅读回执(收件人阅读邮件时会提示回复发件人,表明邮件已收到,并已阅读) 
	        	replyMessage.setHeader("Disposition-Notification-To", emailMessage.getFromAddressList().get(0).get("email"));
	        }
	        replyMessage.setContent(buildMimeMultipart(emailMessage.getEmailText(), emailMessage.getFileList()));
	        replyMessage.setSentDate(new Date());
	        replyMessage.saveChanges();
			Transport.send(replyMessage);
			if (saveSend) {
				folder = (IMAPFolder)store.getFolder(sentFolder);
				MimeMessage sentMessages[] = {(MimeMessage)replyMessage};
	    		folder.appendMessages(sentMessages);
			}
	    	b = true;
	    	log.info("回复成功");
	    	closeStoreAndFloder(folder, store);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return b;
	}
	
	//转发邮件
	public static boolean forwardEmail(OaEmailMessage emailMessage, OaEmailConfig emailConfig, boolean saveSend) {
		boolean b = false;
		try {
			Properties props = new Properties();
			Store store = null;
			props.put("mail.smtp.host", emailConfig.getHost());
			props.setProperty("mail.smtp.port", emailConfig.getPort());
			props.setProperty("mail.imap.proxyauth.user", emailConfig.getHrefPath());
			props.setProperty("mail.imap.class", VitoImapStore.class.getName());
			props.setProperty("LOGINDISABLED", "true");
			Session session = Session.getInstance(props);
			session.addProvider(new VitoImapProvider(Provider.Type.STORE, "imap", null, "Sun Microsystems, Inc", null));;
			URLName urln = new URLName(emailConfig.getUrlName());
			try {
				store = session.getStore(urln);
				store.connect();
			} catch (Exception e) {
				log.info("连接邮件服务器失败");
				e.printStackTrace();
			}
			//先获取要转发的邮件
			IMAPFolder folder = (IMAPFolder)store.getFolder(emailConfig.getFolder()); 
			// 以读写模式打开收件箱 
	        folder.open(Folder.READ_WRITE); 
	        Message forwardMessage = new MimeMessage(session);
	        Message msg = folder.getMessageByUID(emailMessage.getNumber());
	        
        	forwardMessage.setSubject(encodeUtil(emailMessage.getSubject()));
        	forwardMessage.setFrom(new InternetAddress(emailMessage.getFromAddressList().get(0).get("email"), MimeUtility.encodeText(emailMessage.getFromAddressList().get(0).get("personal"))));
        	if (emailMessage.getToAddressList() != null && emailMessage.getToAddressList().size() > 0) {
        		forwardMessage.setRecipients(Message.RecipientType.TO, createAddress(emailMessage.getToAddressList())); //发送
	    	}
	    	if (emailMessage.getCcAddressList() != null && emailMessage.getCcAddressList().size() > 0) {
	    		forwardMessage.setRecipients(Message.RecipientType.CC, createAddress(emailMessage.getCcAddressList()));
	    	}
	    	if (emailMessage.getBccAddressList() != null && emailMessage.getBccAddressList().size() > 0) { //密送
	    		forwardMessage.setRecipients(Message.RecipientType.BCC, createAddress(emailMessage.getBccAddressList()));
	    	}
        	List<Map<String, Object>> oldFileList = emailMessage.getOldAttachFiles();
        	//判断转发邮件是否有原附件
        	if (oldFileList != null && oldFileList.size() > 0 && msg != null) {
 	        	forwardMessage.setContent(buildMimeMultipartHasOldFiles(emailMessage.getEmailText(), emailMessage.getFileList(), msg, oldFileList));
 	        } else {
 	        	forwardMessage.setContent(buildMimeMultipart(emailMessage.getEmailText(), emailMessage.getFileList()));
 	        }
        	//设置优先级(1:紧急   3:普通    5:低) 
        	forwardMessage.setHeader("X-Priority", emailMessage.getPriority());
	        if (emailMessage.isReplyTo()) {//要求阅读回执
	        	//设置回复人(收件人回复此邮件时,默认收件人) 
//		        	message.setReplyTo(createAddress(emailMessage.getFromAddress()));
	        	forwardMessage.setReplyTo(createAddress(emailMessage.getFromAddressList()));
	        	//要求阅读回执(收件人阅读邮件时会提示回复发件人,表明邮件已收到,并已阅读) 
	        	forwardMessage.setHeader("Disposition-Notification-To", emailMessage.getFromAddressList().get(0).get("email"));
	        }
        	forwardMessage.setSentDate(new Date());
        	forwardMessage.saveChanges();
			Transport.send(forwardMessage);
			if (saveSend) {
				folder = (IMAPFolder)store.getFolder(sentFolder);
				MimeMessage sentMessages[] = {(MimeMessage)forwardMessage};
	    		folder.appendMessages(sentMessages);
			}
	    	b = true;
	    	log.info("转发成功");
	    	closeStoreAndFloder(folder, store);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return b;
	}
	
	//草稿箱邮件发送
	public static boolean draftSendEmail(OaEmailMessage emailMessage, OaEmailConfig emailConfig, boolean saveSend) {
		boolean b = false;
		try {
			Properties props = new Properties();
			Store store = null;
			props.put("mail.smtp.host", emailConfig.getHost());
			props.setProperty("mail.smtp.port", emailConfig.getPort());
			props.setProperty("mail.imap.proxyauth.user", emailConfig.getHrefPath());
			props.setProperty("mail.imap.class", VitoImapStore.class.getName());
			props.setProperty("LOGINDISABLED", "true");
			Session session = Session.getInstance(props);
			session.addProvider(new VitoImapProvider(Provider.Type.STORE, "imap", null, "Sun Microsystems, Inc", null));;
			URLName urln = new URLName(emailConfig.getUrlName());
			try {
				store = session.getStore(urln);
				store.connect();
			} catch (Exception e) {
				log.info("连接邮件服务器失败");
				e.printStackTrace();
			}
			//先获取草稿箱的邮件
			IMAPFolder folder = (IMAPFolder)store.getFolder(emailConfig.getFolder()); 
			// 以读写模式打开收件箱 
	        folder.open(Folder.READ_WRITE); 
	        Message draftMessage = new MimeMessage(session);
	        Message msg = folder.getMessageByUID(emailMessage.getNumber());
	        draftMessage.setSubject(encodeUtil(emailMessage.getSubject()));
	        draftMessage.setFrom(new InternetAddress(emailMessage.getFromAddressList().get(0).get("email"), encodeUtil(emailMessage.getFromAddressList().get(0).get("personal"))));
	        if (emailMessage.getToAddressList() != null && emailMessage.getToAddressList().size() > 0) {
	        	draftMessage.setRecipients(Message.RecipientType.TO, createAddress(emailMessage.getToAddressList()));
	    	}
	        if (emailMessage.getCcAddressList() != null && emailMessage.getCcAddressList().size() > 0) {
	        	draftMessage.setRecipients(Message.RecipientType.CC, createAddress(emailMessage.getCcAddressList()));
	    	}
	    	if (emailMessage.getBccAddressList() != null && emailMessage.getBccAddressList().size() > 0) { //密送
	    		draftMessage.setRecipients(Message.RecipientType.BCC, createAddress(emailMessage.getBccAddressList()));
	    	}
	    	draftMessage.setFlag(Flags.Flag.RECENT, true);//新邮件
	        //设置优先级(1:紧急   3:普通    5:低) 
	    	draftMessage.setHeader("X-Priority", emailMessage.getPriority());
	        if (emailMessage.isReplyTo()) {//要求阅读回执
	        	//设置回复人(收件人回复此邮件时,默认收件人) 
	        	draftMessage.setReplyTo(createAddress(emailMessage.getFromAddressList()));
	        	//要求阅读回执(收件人阅读邮件时会提示回复发件人,表明邮件已收到,并已阅读) 
	        	draftMessage.setHeader("Disposition-Notification-To", emailMessage.getFromAddressList().get(0).get("email"));
	        }
        	List<Map<String, Object>> oldFileList = emailMessage.getOldAttachFiles();
        	//判断邮件是否有原附件
        	if (oldFileList != null && oldFileList.size() > 0 && msg != null) {
        		draftMessage.setContent(buildMimeMultipartHasOldFiles(emailMessage.getEmailText(), emailMessage.getFileList(), msg, oldFileList));
 	        } else {
 	        	draftMessage.setContent(buildMimeMultipart(emailMessage.getEmailText(), emailMessage.getFileList()));
 	        }
        	//删除草稿箱邮件(删除原邮件放到判断是否有原附件下)
			msg.setFlag(Flags.Flag.DELETED, true);
        	draftMessage.setSentDate(new Date());
        	draftMessage.saveChanges();
			Transport.send(draftMessage);
			if (saveSend) {
				folder = (IMAPFolder)store.getFolder(sentFolder);
				MimeMessage sentMessages[] = {(MimeMessage)draftMessage};
	    		folder.appendMessages(sentMessages);
			}
			//判断邮箱存储是否打开如果打开则将其关闭
			if(folder!=null && folder.isOpen()){
				folder.close(true); 
			}
			log.info("草稿箱邮件发送成功");
			//删除草稿箱邮件
//			msg.setFlag(Flags.Flag.DELETED, true);
			//删除缓存
    		delCache(emailConfig.getUserId(), OaEmailConstant.FOLDER_TYPE_DRAFT, emailMessage.getNumber(), emailConfig.getEmail());
			log.info("删除草稿箱邮件成功");
	    	b = true;
	    	closeStoreAndFloder(folder, store);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return b;
	}
	
	//草稿箱邮件再次保存
	public static boolean saveDraftAgainEmail(OaEmailMessage emailMessage, OaEmailConfig emailConfig) {
		boolean b = false;
		try {
			Properties props = new Properties();
			Store store = null;
			props.put("mail.smtp.host", emailConfig.getHost());
			props.setProperty("mail.smtp.port", emailConfig.getPort());
			props.setProperty("mail.imap.proxyauth.user", emailConfig.getHrefPath());
			props.setProperty("mail.imap.class", VitoImapStore.class.getName());
			props.setProperty("LOGINDISABLED", "true");
			Session session = Session.getInstance(props);
			session.addProvider(new VitoImapProvider(Provider.Type.STORE, "imap", null, "Sun Microsystems, Inc", null));;
			URLName urln = new URLName(emailConfig.getUrlName());
			try {
				store = session.getStore(urln);
				store.connect();
			} catch (Exception e) {
				log.info("连接邮件服务器失败");
				e.printStackTrace();
			}
			
			//先获取草稿箱的邮件
			IMAPFolder folder = (IMAPFolder)store.getFolder(emailConfig.getFolder()); 
			// 以读写模式打开收件箱 
	        folder.open(Folder.READ_WRITE); 
	        Message msg = folder.getMessageByUID(emailMessage.getNumber());
	        
	        Message draftMessage = new MimeMessage(session);
	        draftMessage.setSubject(encodeUtil(emailMessage.getSubject()));
	        draftMessage.setFrom(new InternetAddress(emailMessage.getFromAddressList().get(0).get("email"), encodeUtil(emailMessage.getFromAddressList().get(0).get("personal"))));
	        if (emailMessage.getToAddressList() != null && emailMessage.getToAddressList().size() > 0) {
	        	draftMessage.setRecipients(Message.RecipientType.TO, createAddress(emailMessage.getToAddressList())); //发送
	    	}
	    	if (emailMessage.getCcAddressList() != null && emailMessage.getCcAddressList().size() > 0) {
	    		draftMessage.setRecipients(Message.RecipientType.CC, createAddress(emailMessage.getCcAddressList()));
	    	}
	    	if (emailMessage.getBccAddressList() != null && emailMessage.getBccAddressList().size() > 0) { //密送
	    		draftMessage.setRecipients(Message.RecipientType.BCC, createAddress(emailMessage.getBccAddressList()));
	    	}
	        //设置优先级(1:紧急   3:普通    5:低) 
	    	draftMessage.setHeader("X-Priority", emailMessage.getPriority());
	        if (emailMessage.isReplyTo()) {//要求阅读回执
	        	//设置回复人(收件人回复此邮件时,默认收件人) 
	        	draftMessage.setReplyTo(createAddress(emailMessage.getFromAddressList()));
	        	//要求阅读回执(收件人阅读邮件时会提示回复发件人,表明邮件已收到,并已阅读) 
	        	draftMessage.setHeader("Disposition-Notification-To", emailMessage.getFromAddressList().get(0).get("email"));
	        }
        	List<Map<String, Object>> oldFileList = emailMessage.getOldAttachFiles();
        	//判断 原邮件是否有原附件
        	if (oldFileList != null && oldFileList.size() > 0 && msg != null) {
        		draftMessage.setContent(buildMimeMultipartHasOldFiles(emailMessage.getEmailText(), emailMessage.getFileList(), msg, oldFileList));
 	        } else {
 	        	draftMessage.setContent(buildMimeMultipart(emailMessage.getEmailText(), emailMessage.getFileList()));
 	        }
        	draftMessage.setSentDate(new Date());
        	draftMessage.saveChanges();
        	MimeMessage draftMessages[] = {(MimeMessage)draftMessage};
	    	folder.appendMessages(draftMessages);
	    	b = true;
			log.info("草稿箱邮件再次保存成功");
			//删除草稿箱邮件
			msg.setFlag(Flags.Flag.DELETED, true);
			//删除缓存
    		delCache(emailConfig.getUserId(), OaEmailConstant.FOLDER_TYPE_DRAFT, emailMessage.getNumber(), emailConfig.getEmail());
			log.info("删除草稿箱邮件成功");
	    	b = true;
	    	closeStoreAndFloder(folder, store);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return b;
	}
	
	public static boolean saveReplyForwardDraftEmail(OaEmailMessage emailMessage, OaEmailConfig emailConfig) {
		boolean b = false;
		try {
			Properties props = new Properties();
			Store store = null;
			props.put("mail.smtp.host", emailConfig.getHost());
			props.setProperty("mail.smtp.port", emailConfig.getPort());
			props.setProperty("mail.imap.proxyauth.user", emailConfig.getHrefPath());
			props.setProperty("mail.imap.class", VitoImapStore.class.getName());
			props.setProperty("LOGINDISABLED", "true");
			Session session = Session.getInstance(props);
			session.addProvider(new VitoImapProvider(Provider.Type.STORE, "imap", null, "Sun Microsystems, Inc", null));;
			URLName urln = new URLName(emailConfig.getUrlName());
			try {
				store = session.getStore(urln);
				store.connect();
			} catch (Exception e) {
				log.info("连接邮件服务器失败");
				e.printStackTrace();
			}
			
			//先获取发件箱或收件箱的邮件
			IMAPFolder folder = (IMAPFolder)store.getFolder(emailConfig.getFolder()); 
			// 以读写模式打开收件箱 
	        folder.open(Folder.READ_WRITE); 
	        Message msg = folder.getMessageByUID(emailMessage.getNumber());
	        
	        Message draftMessage = new MimeMessage(session);
	        draftMessage.setSubject(encodeUtil(emailMessage.getSubject()));
	        draftMessage.setFrom(new InternetAddress(emailMessage.getFromAddressList().get(0).get("email"), encodeUtil(emailMessage.getFromAddressList().get(0).get("personal"))));
	        if (emailMessage.getToAddressList() != null && emailMessage.getToAddressList().size() > 0) {
	        	draftMessage.setRecipients(Message.RecipientType.TO, createAddress(emailMessage.getToAddressList())); //发送
	    	}
	    	if (emailMessage.getCcAddressList() != null && emailMessage.getCcAddressList().size() > 0) {
	    		draftMessage.setRecipients(Message.RecipientType.CC, createAddress(emailMessage.getCcAddressList()));
	    	}
	    	if (emailMessage.getBccAddressList() != null && emailMessage.getBccAddressList().size() > 0) { //密送
	    		draftMessage.setRecipients(Message.RecipientType.BCC, createAddress(emailMessage.getBccAddressList()));
	    	}
	        //设置优先级(1:紧急   3:普通    5:低) 
	    	draftMessage.setHeader("X-Priority", emailMessage.getPriority());
	        if (emailMessage.isReplyTo()) {//要求阅读回执
	        	//设置回复人(收件人回复此邮件时,默认收件人) 
	        	draftMessage.setReplyTo(createAddress(emailMessage.getFromAddressList()));
	        	//要求阅读回执(收件人阅读邮件时会提示回复发件人,表明邮件已收到,并已阅读) 
	        	draftMessage.setHeader("Disposition-Notification-To", emailMessage.getFromAddressList().get(0).get("email"));
	        }
        	List<Map<String, Object>> oldFileList = emailMessage.getOldAttachFiles();
        	//判断 原邮件是否有原附件
        	if (oldFileList != null && oldFileList.size() > 0 && msg != null) {
        		draftMessage.setContent(buildMimeMultipartHasOldFiles(emailMessage.getEmailText(), emailMessage.getFileList(), msg, oldFileList));
 	        } else {
 	        	draftMessage.setContent(buildMimeMultipart(emailMessage.getEmailText(), emailMessage.getFileList()));
 	        }
        	draftMessage.setSentDate(new Date());
        	draftMessage.saveChanges();
        	
			Folder dFolder = store.getFolder(draftFolder);
        	MimeMessage draftMessages[] = {(MimeMessage)draftMessage};
        	dFolder.appendMessages(draftMessages);
	    	b = true;
	    	log.info("转发或回复邮件保存草稿邮件");
			//判断发件文件夹是否打开如果打开则将其关闭
	    	if(dFolder!=null && dFolder.isOpen()){
	    		dFolder.close(true); 
	    	}
	    	closeStoreAndFloder(folder, store);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return b;
	}
	//删除邮件
	public static boolean deleteEmail(Long number, OaEmailConfig emailConfig) {
		boolean b = false;
		try {
			Store store = emailConfig.getStore();
			// 获得收件箱 
			IMAPFolder folder =  (IMAPFolder)store.getFolder(emailConfig.getFolder()); 
	        // 以读写模式打开收件箱 
	        folder.open(Folder.READ_WRITE); 
	        // 获得收件箱的邮件列表 
	        Message message = folder.getMessageByUID(number);
	        if (message != null) {
        		Message[] needCopyMsgs = new Message[1];
        		needCopyMsgs[0] = message;
                // 将获取的邮件对象复制到其他文件夹中
                // 移动意味着要把原有的邮件删除
        		folder.copyMessages(needCopyMsgs, store.getFolder(recycleFolder));
        		//设置为删除
        		message.setFlag(Flags.Flag.DELETED, true);
        		b = true;
        		//删除缓存
        	/*	delCache(emailConfig.getUserId(), emailConfig.getFolderType(), number, emailConfig.getEmail());*/
        		log.info("删除邮件成功");
        	}
	        closeStoreAndFloder(folder, store);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return b;
	}
	
	//批量删除
	public static boolean delBatchEmail(String numbers, OaEmailConfig emailConfig) {
		boolean b = false;
		try {
			Store store = emailConfig.getStore();
			// 获得收件箱 
			IMAPFolder folder =  (IMAPFolder)store.getFolder(emailConfig.getFolder()); 
	        // 以读写模式打开收件箱 
	        folder.open(Folder.READ_WRITE); 
	        // 获得收件箱的邮件列表 
	        String messageNumbers[] = numbers.split(",");
	        for (String number : messageNumbers) {
	        	Message message = folder.getMessageByUID(Long.valueOf(number));
	        	if (message != null) {
	        		Message[] needCopyMsgs = new Message[1];
	        		needCopyMsgs[0] = message;
	                // 将获取的邮件对象复制到其他文件夹中
	                // 移动意味着要把原有的邮件删除
	        		/*emailConfig.setFolderType(OaEmailConstant.FOLDER_TYPE_RECYCLE);*/
	        		folder.copyMessages(needCopyMsgs, store.getFolder(recycleFolder));
	        		//设置为删除
	        		message.setFlag(Flags.Flag.DELETED, true);
	        		b = true;
	        		//删除缓存
	        		delCache(emailConfig.getUserId(), emailConfig.getFolderType(), Long.valueOf(number), emailConfig.getEmail());
	        		log.info("批量删除邮件成功");
	        	}
			}
	        closeStoreAndFloder(folder, store);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return b;
	}
	
	//强力删除，从回收站里删除
	public static boolean forceDeleteEmail(Long number, OaEmailConfig emailConfig) {
		boolean b = false;
		try {
			Store store = emailConfig.getStore();
			// 获得收件箱 
			IMAPFolder folder =  (IMAPFolder)store.getFolder(emailConfig.getFolder()); 
	        // 以读写模式打开收件箱 
	        folder.open(Folder.READ_WRITE); 
	        // 获得收件箱的邮件列表 
	        Message message = folder.getMessageByUID(number);
	        if (message != null) {
                // 移动意味着要把原有的邮件删除
        		//设置为删除
        		message.setFlag(Flags.Flag.DELETED, true);
        		b = true;
        		//删除缓存
        	/*	delCache(emailConfig.getUserId(), emailConfig.getFolderType(), number, emailConfig.getEmail());*/
        		log.info("删除邮件成功");
        	}
	        closeStoreAndFloder(folder, store);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return b;
	}
	
	//批量强力删除，从回收站删除
	public static boolean forceDelBatchEmail(String numbers, OaEmailConfig emailConfig) {
		boolean b = false;
		try {
			Store store = emailConfig.getStore();
			// 获得收件箱 
			IMAPFolder folder =  (IMAPFolder)store.getFolder(emailConfig.getFolder()); 
	        // 以读写模式打开收件箱 
	        folder.open(Folder.READ_WRITE); 
	        // 获得收件箱的邮件列表 
	        String messageNumbers[] = numbers.split(",");
	        for (String number : messageNumbers) {
	        	Message message = folder.getMessageByUID(Long.valueOf(number));
	        	if (message != null) {
	        		//设置为删除
	        		message.setFlag(Flags.Flag.DELETED, true);
	        		b = true;
	        		//删除缓存
	        		delCache(emailConfig.getUserId(), emailConfig.getFolderType(), Long.valueOf(number), emailConfig.getEmail());
	        		log.info("批量删除邮件成功");
	        	}
			}
	        closeStoreAndFloder(folder, store);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return b;
	}
	
	
	
	public static List<OaEmailMessage> getUnreadMessageList(Integer count, OaEmailConfig emailConfig) {
		List<OaEmailMessage> list = new ArrayList<OaEmailMessage>();
		try {
//			Properties props = new Properties();
//			Store store = null;
//			props.setProperty("mail.imap.proxyauth.user", emailConfig.getHrefPath());
//			props.setProperty("mail.imap.class", VitoImapStore.class.getName());
//			props.setProperty("LOGINDISABLED", "true");
//			Session session = Session.getInstance(props);
//			session.addProvider(new VitoImapProvider(Provider.Type.STORE, "imap", null, "Sun Microsystems, Inc", null));;
//			URLName urln = new URLName(url);
//			try {
//				store = session.getStore(urln);
//				store.connect();
//			} catch (Exception e) {
//				log.info("连接邮件服务器失败");
//				e.printStackTrace();
//			}
			Store store = emailConfig.getStore();
			// 获得收件箱 
			IMAPFolder folder =  (IMAPFolder)store.getFolder(emailConfig.getFolder()); 
	        // 以读写模式打开收件箱 
			folder.open(Folder.READ_ONLY);
			//获取未读邮件 
	        FlagTerm ft =  new FlagTerm(new Flags(Flags.Flag.SEEN), false); //false代表未读，true代表已读
	        Message[] messages = folder.search(ft);
	        Integer megLength = messages.length;
			if (messages != null && megLength > 0) {
				if (megLength < count) {
					count = megLength;
				}
				MimeMessage msg = null;
				try {
					for (int i = 0; i < count; i++) {
						msg = (MimeMessage) messages[i]; 
						OaEmailMessage email = new OaEmailMessage();
						email.setUnReadMessageCount(megLength);
						email.setNumber(folder.getUID(messages[i]));
						email.setFromAddressList(parserFromAddress(msg, null));
						//email.setToAddressList(getReceiveAddress(msg, Message.RecipientType.TO, null));
						email.setSubject(msg.getSubject());
						email.setReceivedDate(getSentDate(msg.getReceivedDate()));
						list.add(email);
					}
				} catch (Exception e) {
					log.error("获取未读邮件解析失败");
					e.printStackTrace();
				}
			}
			closeStoreAndFloder(folder, store);
		} catch (Exception e1) {
			log.error("查询异常");
			e1.printStackTrace();
		} 
		return list;
	}
	
	public static boolean updateFlagStatus(String numbers, Integer status, OaEmailConfig emailConfig) {
		boolean b = false;
		try {
			Store store = emailConfig.getStore();
			// 获得收件箱 
			IMAPFolder folder =  (IMAPFolder)store.getFolder(emailConfig.getFolder()); 
			// 以读写模式打开收件箱 
			folder.open(Folder.READ_WRITE);
			boolean flag = false;
			if (status == 1) { //已读
				flag = true;
			} 
			if (status == 0) { //未读
				flag = false;
			}
			String messageNumbers[] = numbers.split(",");
	        for (String number : messageNumbers) {
	        	Message message = folder.getMessageByUID(Long.valueOf(number));
	        	if (message != null) {
    				message.setFlag(Flags.Flag.SEEN, flag);
	        		b = true;
	        		//修改缓存
	        		String key = "email_list_" + emailConfig.getUserId() + "_" + emailConfig.getEmail() + "_"+emailConfig.getFolderType()+"_" + number;
	        		Object obj = JedisTool.getObject(key);
	        		if (obj != null) {
	        			OaEmailMessage em = (OaEmailMessage)obj;
        				em.setSeenFlag(flag);
        				JedisTool.setObject(key, em);
        				JedisTool.del("email_obj_" + emailConfig.getUserId() + "_" + emailConfig.getEmail() + "_"+emailConfig.getFolderType()+"_" + number);
	        		}
	        		log.info("批量修改邮件状态成功");
	        	}
			}
	        closeStoreAndFloder(folder, store);
		} catch (Exception e) {
			log.error("查询异常");
			e.printStackTrace();
		}
		return b;
	}
	
	/**
	 * 组装查询条件
	 * @param emailMessage
	 * @return
	 */
	private static List<SearchTerm> getSearchConditionList(OaEmailMessage emailMessage) {
		List<SearchTerm> list = new ArrayList<SearchTerm>();
		try {
			if (emailMessage.getPosition() != null && emailMessage.getPosition() == 1) { //检索位置 1主题， 2 正文
				if (StringUtils.isNotBlank(emailMessage.getKeywords())) {
					SearchTerm subjectTerm = new OaSubjectTerm(emailMessage.getKeywords());
					list.add(subjectTerm);
				}
			}
			
			if (emailMessage.getPosition() != null && emailMessage.getPosition() == 2) {
				if (StringUtils.isNotBlank(emailMessage.getKeywords())) {
					SearchTerm bodyTerm = new OaBodyTerm(emailMessage.getKeywords());
					list.add(bodyTerm);
				}
			}
			//手机端按标题搜索
			if (StringUtils.isNotBlank(emailMessage.getSubject())) {
				SearchTerm subjectTerm = new OaSubjectTerm(emailMessage.getSubject());
				list.add(subjectTerm);
			}
			//手机端按正文搜索
			if (StringUtils.isNotBlank(emailMessage.getEmailText())) {
				SearchTerm bodyTerm = new OaBodyTerm(emailMessage.getEmailText());
				list.add(bodyTerm);
			}
	        if (emailMessage.getReadFlag() != null && emailMessage.getReadFlag() != -1) {
	        	FlagTerm ft = null;
	        	if (emailMessage.getReadFlag() == 0) {
	        		ft = new FlagTerm(new Flags(Flags.Flag.SEEN), false); //false代表未读，true代表已读
	        	}
	        	if (emailMessage.getReadFlag() == 1) {
	        		ft = new FlagTerm(new Flags(Flags.Flag.SEEN), true); //false代表未读，true代表已读
	        	}
	        	list.add(ft);
	        }
	        if (StringUtils.isNotBlank(emailMessage.getFromAddress())) {
	        	//进行编码，防止输入汉字转InternetAddress出错
	        	String base64FromAddress = encodeUtil(emailMessage.getFromAddress());
				String searchFromAddress = "";
				if (base64FromAddress.contains("=?")) {
					searchFromAddress = base64FromAddress.substring(10, base64FromAddress.length()-2);
				} else {
					searchFromAddress = base64FromAddress;
				}
	        	SearchTerm fromTerm = new OaFromTerm(new InternetAddress(searchFromAddress));
	        	list.add(fromTerm);
	        }
	        if (StringUtils.isNotBlank(emailMessage.getFromPersonal())) {
	        	SearchTerm fromStringTerm = new OaFromStringTerm(emailMessage.getFromPersonal());
	        	list.add(fromStringTerm);
	        }
	        //收件人
	        if (StringUtils.isNotBlank(emailMessage.getRecipientAddress())) {
	        	//进行编码，防止输入汉字转InternetAddress出错
	        	String base64RecipientAddress = encodeUtil(emailMessage.getRecipientAddress());
				String searchRecipientAddress = "";
				if (base64RecipientAddress.contains("=?")) {
					searchRecipientAddress = base64RecipientAddress.substring(10, base64RecipientAddress.length()-2);
				} else {
					searchRecipientAddress = base64RecipientAddress;
				}
	        	SearchTerm recipientTerm = new OaRecipientTerm(Message.RecipientType.TO, new InternetAddress(searchRecipientAddress));
	        	list.add(recipientTerm);
	        }
	        if (StringUtils.isNotBlank(emailMessage.getRecipientPersonal())) {
	        	SearchTerm recipientStringTerm = new OaRecipientStringTerm(Message.RecipientType.TO, emailMessage.getRecipientPersonal());
	        	list.add(recipientStringTerm);
	        }
	        //发送时间
	        if (StringUtils.isNotBlank(emailMessage.getSendDateStart())) {
	        	Date startDate = DateUtils.formatToDateTime(emailMessage.getSendDateStart() + DateUtils.START_TIME_SUFFIX);
	        	SearchTerm comparisonTermGe = new SentDateTerm(ComparisonTerm.GE, startDate);//>=
	        	list.add(comparisonTermGe);
	        }
	        if (StringUtils.isNotBlank(emailMessage.getSendDateEnd())) {
	        	Date endDate = DateUtils.formatToDateTime(emailMessage.getSendDateEnd() + DateUtils.END_TIME_SUFFIX);
	        	SearchTerm comparisonTermLe = new SentDateTerm(ComparisonTerm.LE, endDate); //<=
	        	list.add(comparisonTermLe);
	        }
	        if (StringUtils.isNotBlank(emailMessage.getReceivedDateStart())) {
	        	Date startDate = DateUtils.formatToDateTime(emailMessage.getReceivedDateStart() + DateUtils.START_TIME_SUFFIX);
	        	SearchTerm comparisonTermGe = new ReceivedDateTerm(ComparisonTerm.GE, startDate);//>=
	        	list.add(comparisonTermGe);
	        }
	        if (StringUtils.isNotBlank(emailMessage.getReceivedDateEnd())) {
	        	Date endDate = DateUtils.formatToDateTime(emailMessage.getReceivedDateEnd() + DateUtils.END_TIME_SUFFIX);
	        	SearchTerm comparisonTermLe = new ReceivedDateTerm(ComparisonTerm.LE, endDate); //<=
	        	list.add(comparisonTermLe);
	        }
	       
		} catch (Exception e) {
			log.error("组装查询条件出错");
			e.printStackTrace();
		}
        return list;
	}
	
	private static DataGrid<OaEmailMessage> getNotSearchList(IMAPFolder folder, OaEmailMessage emailMessage, OaEmailConfig emailConfig) {
		DataGrid<OaEmailMessage> emailPager = new DataGrid<OaEmailMessage>();
		try {
			List<OaEmailMessage> emList = new ArrayList<OaEmailMessage>();
	        int end = 0;
	        int start = 1;
	        emailPager.setTotal(folder.getMessages().length);
	        if (emailMessage.getPageNo_() == 1) {
	        	end = start + emailMessage.getPageSize_() - 1;
	        } else {
	        	start = (emailMessage.getPageNo_() - 1) * emailMessage.getPageSize_() + 1;
	        	end = start + emailMessage.getPageSize_() - 1;
	        }
	        if (end > emailPager.getTotal()) {
	        	end = emailPager.getTotal();
	        }
	        Message[] messages = folder.getMessages(start, end);
	        OaEmailMessage em = null;
	        MimeMessage msg = null;
	        for (Message message : messages) {
	        	msg = (MimeMessage)message;
	        	em = getEmailItem(msg, emailConfig.getUserId(), emailConfig.getFolderType(), folder.getUID(message), emailConfig.getEmail());
	        	emList.add(em);
	        }
	        emailPager.setRows(emList);
			if(folder!=null && folder.isOpen()){
	    		folder.close(true); 
	    	}
		} catch (Exception e) {
			log.error("getNotSearchList查询出错" + e);
			e.printStackTrace();
		}
		return emailPager;
	}
	
	private static DataGrid<OaEmailMessage> getSearchList(IMAPFolder folder, SearchTerm andTerm, OaEmailMessage emailMessage, OaEmailConfig emailConfig) {
		DataGrid<OaEmailMessage> emailPager = new DataGrid<OaEmailMessage>();
		try {
			Message[] messages = folder.search(andTerm);
			int itemEnd = 0;
			int itemStart = 0;
			
			int messageLength = messages.length;
			if (messageLength > 0) {
				if (emailMessage.getPageNo_() != 1) {
					itemStart = (emailMessage.getPageNo_()-1) * emailMessage.getPageSize_();
				}
				if(messageLength > (emailMessage.getPageNo_() * emailMessage.getPageSize_())) {
					itemEnd = emailMessage.getPageNo_() * emailMessage.getPageSize_();
				} else {
					itemEnd = messageLength;
				}
			}
			emailPager.setTotal(messageLength);
			List<OaEmailMessage> emList = new ArrayList<OaEmailMessage>();
			OaEmailMessage em = null;
			for (int i = itemStart; i < itemEnd; i++) {
				MimeMessage msg = (MimeMessage) messages[i];
//				MimeMessage msg = new MimeMessage((MimeMessage)messages[i]); 
				em = getEmailItem(msg, emailConfig.getUserId(), emailConfig.getFolderType(), folder.getUID(messages[i]), emailConfig.getEmail());
	        	emList.add(em);
			}
			emailPager.setRows(emList);
			if(folder!=null && folder.isOpen()){
	    		folder.close(true); 
	    	}
		} catch (Exception e) {
			log.error("getSearchList搜索查询出错" + e);
			e.printStackTrace();
		}
		return emailPager;
	}
	
	private static OaEmailMessage getEmailItem(MimeMessage msg, String userId, int folderType, Long UID, String email) {
    	String eKey = "email_list_" + userId + "_" + email + "_" + folderType + "_" + UID;
    	OaEmailMessage em = null;
    	try {
    		Object obj = JedisTool.getObject(eKey);
    		if (obj != null) {
    			em = (OaEmailMessage)obj;
        	} else {
            	em = new OaEmailMessage();
            	em.setNumber(UID);
            	if (folderType == OaEmailConstant.FOLDER_TYPE_INBOX) {
            		Flags flags = msg.getFlags();
            		if (flags.contains(Flags.Flag.SEEN)) {
            			em.setSeenFlag(true);
            		} else {
            			em.setSeenFlag(false);
            		}
            	}
            	if (folderType == OaEmailConstant.FOLDER_TYPE_INBOX) {
            		em.setFromAddressList(parserFromAddress(msg, null));
            		em.setReceivedDate(getSentDate(msg.getReceivedDate()));
            	}
            	if (folderType == OaEmailConstant.FOLDER_TYPE_SEND || folderType == OaEmailConstant.FOLDER_TYPE_DRAFT) {
            		//TODO ...密送和抄送也加入
            		em.setToAddressList(getReceiveAddress(msg, Message.RecipientType.TO, null));
            		em.setCcAddressList(getReceiveAddress(msg, Message.RecipientType.CC, null));
            		em.setSendDate(getSentDate(msg.getSentDate()));
            	}
            	em.setSubject(msg.getSubject());
            	StringBuffer bodyText = new StringBuffer();
            	em.setEmailText(getMailContent(bodyText, msg));
            	em.setContainAttachment(isContainAttachment(msg));
            	em.setPriority(getPriority(msg));
            	
            	//添加缓存
            	addCache(eKey, userId, em, email);
        	}
    	}catch (Exception e) {
			log.error("查询getEmailItem出错");
			e.printStackTrace();
		}
		return em;
	}
	
	/**添加邮件缓*/
	private static void addCache(String key, String userId, OaEmailMessage em, String email) {
		try {
			JedisTool.setObject(key, em);
			List<?> keyList = JedisTool.getList("email_list_" + userId + "_" + email);
			if (keyList != null && keyList.size() > 0) {
				JedisTool.appendList("email_list_" + userId + "_" + email, key);
			} else {
				List<String> newKeyList = new ArrayList<String>();
				log.info("添加邮件列表缓存：key: email_list_" + key);
				newKeyList.add(key);
				JedisTool.setList("email_list_" + userId + "_" + email, newKeyList);
			}
		} catch (Exception e) {
			log.error("添加邮件缓存出错");
			e.printStackTrace();
		}
	}
	
	/**删除缓存*/
	private static void delCache(String userId, Integer folderType, Long number, String email) {
		try {
			String key = userId + "_" + email + "_" + folderType + "_" + number;
			JedisTool.del("email_list_" + key);
			List<?> keyList = JedisTool.getList("email_list_" + userId + "_" + email);
			if (keyList != null && keyList.size() > 0) {
				log.info("删除邮件缓存：key: email_list_" + key);
				keyList.remove("email_list_" + key);
				JedisTool.setList("email_list_" + userId+ "_" + email, keyList);
			}
			JedisTool.del("email_obj_" + key);
			List<?> keyObjList = JedisTool.getList("email_obj_" + userId + "_" + email);
			if (keyObjList != null && keyObjList.size() > 0) {
				log.info("删除邮件缓存：key: email_obj_" + key);
				keyObjList.remove("email_obj_" + key);
				JedisTool.setList("email_obj_" + userId+ "_" + email, keyObjList);
			}
		} catch (Exception e) {
			log.error("删除邮件缓存出错");
			e.printStackTrace();
		}
	}
	
	public static Address[] createAddress(List<Map<String, String>> toAddressList) throws Exception {
		if (toAddressList != null && toAddressList.size() > 0) {
			Address[] addresses = new Address[toAddressList.size()];
			for (int i = 0; i < toAddressList.size(); i++) {
				System.out.println(encodeUtil(toAddressList.get(i).get("personal")));
				addresses[i] = new InternetAddress(toAddressList.get(i).get("email"), encodeUtil(toAddressList.get(i).get("personal")));//MimeUtility.encodeText(
			}
			return addresses;
		} else {
			return null;
		}
	}
	/**
	 * 解析发件人
	 * @param from
	 * @return
	 * @throws MessagingException 
	 */
	public static List<Map<String, String>> parserFromAddress(MimeMessage msg, String userId) throws MessagingException {
		InternetAddress address[] = (InternetAddress[]) msg.getFrom();
		List<Map<String, String>> mapList = new ArrayList<Map<String, String>>();
		Map<String, String> map = new HashMap<String, String>();
		if (address[0] != null) {
			String from = address[0].getAddress(); 
			String personal = address[0].getPersonal();
			if (checkHasContacts(from, userId)) { //用户可以添加到外部联系人中
				map.put("canadd", "true");
			}
			map.put("email", from);
			if (personal != null && personal != "") {
				personal = personal.replaceAll("\"", "");
			}
			map.put("personal", personal);
			mapList.add(map);
		}
		return mapList;
	}
	
	public static String getSentDate(Date sendDate) throws Exception {
		String strSentDate = "";
		if (sendDate != null) {
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			strSentDate = format.format(sendDate);
		}
		return strSentDate;
	}
	
	/**  
     * 判断邮件中是否包含附件  
     * @param msg 邮件内容  
     * @return 邮件中存在附件返回true，不存在返回false  
     * @throws MessagingException  
     * @throws IOException  
     */    
    private static boolean isContainAttachment(Part part) throws MessagingException, IOException {    
        boolean flag = false;    
        if (part.isMimeType("multipart/*")) {    
            MimeMultipart multipart = (MimeMultipart) part.getContent();    
            int partCount = multipart.getCount();    
            for (int i = 0; i < partCount; i++) {    
                BodyPart bodyPart = multipart.getBodyPart(i);    
                String disp = bodyPart.getDisposition();    
                if (disp != null && (disp.equalsIgnoreCase(Part.ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE))) {  
                    flag = true;    
                } else if (bodyPart.isMimeType("multipart/*")) {    
                    flag = isContainAttachment(bodyPart);    
                } else {    
                    String contentType = bodyPart.getContentType();    
                    if (contentType.indexOf("application") != -1) {    
                        flag = true;    
                    }      
                    if (contentType.indexOf("name") != -1) {    
                        flag = true;    
                    }     
                }    
                    
                if (flag) break;    
            }    
        } else if (part.isMimeType("message/rfc822")) {    
            flag = isContainAttachment((Part)part.getContent());    
        }    
        return flag;    
    }
    
    /** 
     * 获得邮件的优先级 
     * @param msg 邮件 
     * @return  1(High):紧急  3:普通(Normal)  5:低(Low) 
     * @throws MessagingException 
     */  
    private static String getPriority(MimeMessage msg) throws MessagingException {  
        String priority = "普通";   
        String[] headers = msg.getHeader("X-Priority");   
        if (headers != null) {   
            String headerPriority = headers[0];   
            if (headerPriority.indexOf("1") != -1 || headerPriority.indexOf("High") != -1) {  
                priority = "紧急";   
            } else if (headerPriority.indexOf("5") != -1 || headerPriority.indexOf("Low") != -1) {   
                priority = "低";   
            }else {   
                priority = "普通";  
            }  
        }   
        return priority;   
    }
    
    /**  
     * 根据收件人类型，获取邮件收件人、抄送和密送地址。如果收件人类型为空，则获得所有的收件人  
     * <p>Message.RecipientType.TO  收件人</p>  
     * <p>Message.RecipientType.CC  抄送</p>  
     * <p>Message.RecipientType.BCC 密送</p>  
     * @param msg 邮件内容  
     * @param type 收件人类型  
     * @return 收件人1 <邮件地址1>, 收件人2 <邮件地址2>, ...  
     * @throws MessagingException  
     */    
    private static List<Map<String, String>> getReceiveAddress(MimeMessage msg, Message.RecipientType type, String userId) throws MessagingException {    
    	List<Map<String, String>> mapList = new ArrayList<Map<String, String>>();
        Address[] addresss = null;    
        if (type == null) {    
            addresss = msg.getAllRecipients();    
        } else {    
            addresss = msg.getRecipients(type);    
        }    
            
        if (addresss != null) {
        	for (Address address : addresss) {    
        		Map<String, String> map = new HashMap<String, String>();
        		InternetAddress internetAddress = (InternetAddress)address;   
        		String from = internetAddress.getAddress(); 
        		
    			String personal = internetAddress.getPersonal();
    			if (checkHasContacts(from, userId)) { //用户可以添加到外部联系人中
    				map.put("canadd", "true");
    			}
    			map.put("email", from);
    			if (personal != null && personal != "") {
    				personal = personal.replaceAll("\"", "");
    			}
    			map.put("personal", personal);
    			mapList.add(map);
        	}    
        }
            
        return mapList;    
    } 
    
    /**
     * 检查联系人是否已保存
     * @return
     */
    private static boolean checkHasContacts(String email, String userId) {
    	if (StringUtils.isNotBlank(email) && StringUtils.isNotBlank(userId)) {
    		ExternalContacts contacts = new ExternalContacts();
    		contacts.setContactsMail(email);
    		contacts.setUserId(userId);
    		if (baseUserService.getUserMail(email) > 0 || baseUserService.getContactsByMail(contacts) != null) {
    			return false;
    		} else {
    			return true;
    		}
    	} else {
    		return false;
    	}
    }
    
    
  //获得邮件文本内容
    public static String getMailContent(StringBuffer bodyText,Part part) throws Exception {
    	String contentType = part.getContentType(); 
    	int nameIndex = contentType.indexOf("name");  
    	boolean conName = false; 
    	if (nameIndex != -1) {
    		conName = true;   
    	}   
    	if (part.isMimeType("text/plain") && !conName) {    
    		bodyText.append(part.getContent().toString());    
        } else if (part.isMimeType("text/html") && !conName) {    
        	bodyText.append(part.getContent().toString());    
        } else if (part.isMimeType("multipart/*")) {    
            Multipart multipart = (Multipart) part.getContent();    
            int counts = multipart.getCount();
            boolean hasHtml = checkHasHtml(multipart); //这里校验是否有text/html内容
            for (int i = 0; i < counts; i++) {  
            	Part temp = multipart.getBodyPart(i);
            	if (temp.isMimeType("text/plain") && hasHtml) { 
            		//有html格式的则不显示无格式文档的内容    
    			} else {
    				getMailContent(bodyText, temp);    
    			}

            }    
        } else if (part.isMimeType("message/rfc822")) {    
            getMailContent(bodyText, (Part) part.getContent());    
        } else {} 
    	return bodyText.toString();
    }
    
    public static boolean checkHasHtml(Multipart part) throws MessagingException, IOException {
    	boolean hasHtml = false;
    	int count = part.getCount();
    	for (int i = 0; i < count; i++) {
    		Part bodyPart = part.getBodyPart(i);
    		if (bodyPart.isMimeType("text/html")) {
    			hasHtml = true;
    			break;
    		}
    	}
    	return hasHtml;
    }

    //获取邮件附件名
    public static List<Map<String, Object>> getFileNames(List<Map<String, Object>> fileList, Part part) throws Exception{
    	if (part.isMimeType("multipart/*")) {    
            MimeMultipart multipart = (MimeMultipart) part.getContent();    
            int partCount = multipart.getCount();    
            for (int i = 0; i < partCount; i++) { 
            	BodyPart bodyPart = multipart.getBodyPart(i);    
                String dispostion = bodyPart.getDisposition();   
                if (dispostion != null) {
					if (dispostion.equalsIgnoreCase(Part.ATTACHMENT)) {
						Map<String, Object> map = new HashMap<String, Object>();
						map.put("fileName", parseFileName(bodyPart));
						map.put("fileSize", bodyPart.getSize());
						map.put("fileId", i);
						fileList.add(map);
					} else if (dispostion.equalsIgnoreCase(Part.INLINE)) {  
						Map<String, Object> map = new HashMap<String, Object>();
						map.put("fileName", parseFileName(bodyPart));
						map.put("fileSize", bodyPart.getSize());
						map.put("fileId", i);
						fileList.add(map);
					} else {  
						
					}  
				}
            }
    	} else if (part.isMimeType("message/rfc822")) {
    		getFileNames(fileList, (Part) part.getContent());
		}
    	return fileList;
    }
    
  //解析附件名
    private static String parseFileName(Part part) throws Exception{  
		String fileName = part.getFileName();  
		fileName = MimeUtility.decodeText(fileName);  
		String name = fileName;  
		if (fileName != null) {  
		    int index = fileName.lastIndexOf("/");  
		    if (index != -1) {  
		        name = fileName.substring(index + 1);  
		    }  
		}  
		return name;  
	} 
    /**
     * 构建邮件
     */
	public static Multipart buildMimeMultipart(String msgContent, List<Map<String, Object>> fileList) throws Exception {
		Multipart mp = new MimeMultipart();// 多部分实现   
		try {
			//设置附件
			if (fileList != null && fileList.size() > 0) {
				for (Map<String, Object> map : fileList) {
					if (map.get("filePath") != null && map.get("fileName") != null) {
						MimeBodyPart attachment = new MimeBodyPart();
						attachment = createAttachment(map.get("filePath").toString(), map.get("fileName").toString());
						mp.addBodyPart(attachment);
					}
				}
			}
			MimeBodyPart content = createContent(msgContent, null);  
			mp.addBodyPart(content);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return mp;
	}
	
	/**
	 * 构建邮件含原邮件附件
	 */
	public static Multipart buildMimeMultipartHasOldFiles(String msgContent, List<Map<String, Object>> fileList, Message msg, List<Map<String, Object>> oldFileList) throws Exception {
		Multipart mp = new MimeMultipart();// 多部分实现   
		try {
			//设置附件
			if (fileList != null && fileList.size() > 0) {
				for (Map<String, Object> map : fileList) {
					MimeBodyPart attachment = new MimeBodyPart();
					attachment = createAttachment(map.get("filePath").toString(), map.get("fileName").toString());
					mp.addBodyPart(attachment);
				}
			}
			//将原邮件附件添加到bodyPart中
			List<BodyPart> list = new ArrayList<BodyPart>();
			list = getBodyPartList(list, msg, oldFileList);
			for (int i = 0; i < list.size(); i++) {
				mp.addBodyPart(list.get(i));
			}
			MimeBodyPart content = createContent(msgContent, null);  
			mp.addBodyPart(content);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return mp;
	}
	
	/**
	 * 获取原邮件附件
	 */
	public static List<BodyPart> getBodyPartList(List<BodyPart> partList, Part part, List<Map<String, Object>> oldFileList) throws Exception {
		//将原邮件附件添加到bodyPart中
		if (part.isMimeType("multipart/*")) {
			String fileName = "";
			Multipart oldmp = (Multipart) part.getContent();
			for (int i = 0; i < oldmp.getCount(); i++) {
				for (int j = 0; j < oldFileList.size(); j++) {
					if (i == Integer.valueOf(oldFileList.get(j).get("fileId").toString())) {
						BodyPart mpart = oldmp.getBodyPart(i);
						String disposition = mpart.getDisposition();
						if ((disposition != null) && ((disposition.equals(Part.ATTACHMENT)) || (disposition.equals(Part.INLINE)))) {
							fileName = mpart.getFileName();
							if (fileName.toLowerCase().indexOf("utf") != -1){
								fileName = MimeUtility.decodeText(fileName);
							}
							System.out.println(i + "," + fileName);
							if (fileName.equals(oldFileList.get(j).get("fileName").toString())) {
								//获取到原邮件附件并先放入partList
								partList.add(mpart);
							}
						} else if (mpart.isMimeType("multipart/*")) {
							getBodyPartList(partList, mpart, oldFileList);
						} else {
							fileName = mpart.getFileName();
							if ((fileName != null) && (fileName.toLowerCase().indexOf("utf-8") != -1)) {
								fileName = MimeUtility.decodeText(fileName);
								System.out.println(i + "," + fileName);
								if (fileName.equals(oldFileList.get(j).get("fileName").toString())) {
									partList.add(mpart);
								}
							}
						}
					}
				}
			}
		} else if (part.isMimeType("message/rfc822")) {
			getBodyPartList(partList, (Part) part.getContent(), oldFileList);
		}
		return partList;
	}
	
	/**
	 * 附件
	 */
	public static MimeBodyPart createAttachment(String filePath, String fileName) throws Exception {
		MimeBodyPart attachmentPart = new MimeBodyPart();
		FileDataSource fileds = new FileDataSource(filePath);  
        attachmentPart.setDataHandler(new DataHandler(fileds));
        attachmentPart.setFileName(MimeUtility.encodeText(fileName,"UTF-8", null)); // 解决附件名称乱码
		return attachmentPart;
	}
	
	/**
	 * 图文组合
	 */
	public static MimeBodyPart createContent(String body, String fileName) throws Exception {
		// 用于保存最终正文部分  
        MimeBodyPart contentBody = new MimeBodyPart();
		MimeBodyPart textBody = new MimeBodyPart();  
		// 用于组合文本和图片，"related"型的MimeMultipart对象  
        MimeMultipart contentMulti = new MimeMultipart("related");  
        
        textBody.setContent(body, "text/html;charset=utf-8");  
        contentMulti.addBodyPart(textBody); 
        //正文的图片部分  
        if (fileName != null) {
        	MimeBodyPart jpgBody = new MimeBodyPart();  
        	FileDataSource fds = new FileDataSource(fileName);  
        	jpgBody.setDataHandler(new DataHandler(fds));  
        	jpgBody.setContentID("login_jpg");  
        	contentMulti.addBodyPart(jpgBody);
        }
     // 将上面"related"型的 MimeMultipart 对象作为邮件的正文  
        contentBody.setContent(contentMulti);  
		return contentBody;
	}
	
	/**   
     * * 判断此邮件是否需要回执，如果需要回执返回"true",否则返回"false"   
     */    
    public static boolean getReplySign(MimeMessage msg) throws MessagingException {    
        boolean replysign = false;    
        String needreply[] = msg.getHeader("Disposition-Notification-To");    
        if (needreply != null) {    
            replysign = true;    
        }
        return replysign;  
    }
    
    private static String encodeUtil(String content) throws UnsupportedEncodingException {
    	if (content != null && content != "") {
    		return MimeUtility.encodeText(content, "UTF-8", "B");
    	} else {
    		return "";
    	}
    }

    private static void closeStoreAndFloder(Folder folder, Store store) {
    	//判断发件文件夹是否打开如果打开则将其关闭
    	try {
    		if(folder!=null && folder.isOpen()){
    			folder.close(true); 
    		}
    		//判断邮箱存储是否打开如果打开则将其关闭
    		if(store!=null && store.isConnected()){
    			store.close();
    		}
    	} catch (Exception e) {
			e.printStackTrace();
		}
    }
    
}
